package com.yeziji.utils.expansion;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.NonNull;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Spring 简化工具类
 *
 * @author hwy
 * @since 2024/05/08 17:36
 **/
public class Spring2 {
    /**
     * 获取扫描器(获取独立组件并且不是一个注解的容器)
     *
     * @param environment 扫描指定的 spring 环境
     * @return {@link ClassPathScanningCandidateComponentProvider}
     */
    public static ClassPathScanningCandidateComponentProvider getScanner(Environment environment, ResourceLoader resourceLoader) {
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false, environment) {
            @Override
            protected boolean isCandidateComponent(@NonNull AnnotatedBeanDefinition beanDefinition) {
                boolean isCandidate = false;
                if (beanDefinition.getMetadata().isIndependent()) {
                    if (!beanDefinition.getMetadata().isAnnotation()) {
                        isCandidate = true;
                    }
                }
                return isCandidate;
            }
        };
        scanner.setResourceLoader(resourceLoader);
        return scanner;
    }

    /**
     * 扫描获取 basePackages
     * @param clazz 扫描的注解类
     * @param importingClassMetadata 入驻类的信息
     */
    public static Set<String> getBasePackages(Class<?> clazz, AnnotationMetadata importingClassMetadata) {
        // 获取到 clazz 注解所有属性
        Map<String, Object> attributes = importingClassMetadata.getAnnotationAttributes(clazz.getCanonicalName());
        Set<String> basePackages = new HashSet<>();
        assert attributes != null;
        // value 属性是否有配置值，如果有则添加
        for (String pkg : (String[]) attributes.get("value")) {
            if (StringUtils.hasText(pkg)) {
                basePackages.add(pkg);
            }
        }

        // basePackages 属性是否有配置值，如果有则添加
        for (String pkg : (String[]) attributes.get("basePackages")) {
            if (StringUtils.hasText(pkg)) {
                basePackages.add(pkg);
            }
        }

        // 如果上面两步都没有获取到basePackages，那么这里就默认使用当前项目启动类所在的包为 basePackages
        if (basePackages.isEmpty()) {
            basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName()));
        }
        return basePackages;
    }
}
